<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="YQpWD" id="YQpWD"><span data-lake-id="ua54c3ff9" id="ua54c3ff9">典型回答</span></h1>
  <p data-lake-id="ua35b0253" id="ua35b0253"><span data-lake-id="ub499ce94" id="ub499ce94">聚簇索引（Clustered Index）和非聚簇索引（Non-clustered Index）是数据库中的两种索引类型，它们在组织和存储数据时有不同的方式。</span></p>
  <p data-lake-id="u35336f10" id="u35336f10"><span data-lake-id="u9cc11ca7" id="u9cc11ca7">​</span><br></p>
  <p data-lake-id="u135f30ac" id="u135f30ac"><strong><span data-lake-id="uc954fb1c" id="uc954fb1c">聚簇索引</span></strong><span data-lake-id="u9f6fe3ca" id="u9f6fe3ca">，简单点理解就是将数据与索引放到了一起，找到索引也就找到了数据。也就是说，对于聚簇索引来说，他的非叶子节点上存储的是索引字段的值，而他的叶子节点上存储的是这条记录的整行数据。</span></p>
  <p data-lake-id="uaf558ace" id="uaf558ace"><span data-lake-id="ub784baeb" id="ub784baeb">​</span><br></p>
  <p data-lake-id="uaddaf6e6" id="uaddaf6e6"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1692358803187-bd4cb9e4-994d-4227-bbac-2f4a01bab92b.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_30%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="u11c4897e" id="u11c4897e"><span data-lake-id="ub239f356" id="ub239f356">​</span><br></p>
  <p data-lake-id="uf3572ac4" id="uf3572ac4"><strong><span data-lake-id="ua5aa98e8" id="ua5aa98e8">在InnoDB中，聚簇索引（Clustered Index）指的是按照每张表的主键构建的一种索引方式</span></strong><span data-lake-id="u974d6247" id="u974d6247">，它是将表数据按照主键的顺序存储在磁盘上的一种方式。这种索引方式保证了行的物理存储顺序与主键的逻辑顺序相同，因此查找聚簇索引的速度非常快。</span></p>
  <p data-lake-id="u2562ede5" id="u2562ede5"><br></p>
  <p data-lake-id="u98eff9b0" id="u98eff9b0"><strong><span data-lake-id="u7f1a9f37" id="u7f1a9f37">非聚簇索引</span></strong><span data-lake-id="ubc7bc540" id="ubc7bc540">，就是将数据与索引分开存储，叶子节点包含索引字段值及指向数据页数据行的逻辑指针。</span></p>
  <p data-lake-id="u138a52c1" id="u138a52c1"><span data-lake-id="uef6e55fa" id="uef6e55fa">​</span><br></p>
  <p data-lake-id="u1535f469" id="u1535f469"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1692358781484-6c40992b-7841-4778-ad93-9043f83984e8.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_30%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="uf5e2394c" id="uf5e2394c"><br></p>
  <p data-lake-id="udf16e030" id="udf16e030"><strong><span data-lake-id="ueb35b516" id="ueb35b516">在Innodb中，非聚簇索引（Non-clustered Index）是指根据非主键字段创建的索引</span></strong><span data-lake-id="u8bc126df" id="u8bc126df">，也就是通常所说的二级索引。它不影响表中数据的物理存储顺序，而是单独创建一张索引表，用于存储索引列和对应行的指针。</span></p>
  <p data-lake-id="ud07cd819" id="ud07cd819"><span data-lake-id="uf25955a4" id="uf25955a4">​</span><br></p>
  <p data-lake-id="ua2b50242" id="ua2b50242"><span data-lake-id="ueb129672" id="ueb129672">在InnoDB中，主键索引就是聚簇索引，而非主键索引，就是非聚簇索引，所以在InnoDB中：</span></p>
  <ul list="ued5e80e3">
   <li fid="uae8845d1" data-lake-id="ue7b44912" id="ue7b44912"><strong><span data-lake-id="uf428ad19" id="uf428ad19">对于聚簇索引来说，他的非叶子节点上存储的是索引值，而它的叶子节点上存储的是整行记录。</span></strong></li>
   <li fid="uae8845d1" data-lake-id="u511231eb" id="u511231eb"><strong><span data-lake-id="ue6af1fed" id="ue6af1fed">对于非聚簇索引来说，他的非叶子节点上存储的都是索引值，而它的叶子节点上存储的是主键的值。</span></strong></li>
  </ul>
  <p data-lake-id="u406a4e7a" id="u406a4e7a"><span data-lake-id="u7683f72e" id="u7683f72e">​</span><br></p>
  <p data-lake-id="u54eec5b2" id="u54eec5b2"><strong><span data-lake-id="u5c9aac8b" id="u5c9aac8b">所以，通过非聚簇索引的查询，需要进行一次回表，就是先查到主键ID，在通过ID查询所需字段。</span></strong></p>
  <p data-lake-id="u677e1ff9" id="u677e1ff9"><strong><span data-lake-id="u6da41f60" id="u6da41f60">​</span></strong><br></p>
  <p data-lake-id="u8d169e76" id="u8d169e76"><span data-lake-id="u3da53392" id="u3da53392">​</span><br></p>
  <h2 data-lake-id="jO1tO" id="jO1tO"><span data-lake-id="ubb7c6637" id="ubb7c6637">没有创建主键怎么办？</span></h2>
  <p data-lake-id="u49b57f0a" id="u49b57f0a"><br></p>
  <p data-lake-id="ubb85e6b7" id="ubb85e6b7"><span data-lake-id="ua6e8b5cf" id="ua6e8b5cf">我们知道，Innodb中的聚簇索引是按照每张表的主键构造一个B+树，那么不知道大家有没有想过这个问题，如果我们在表结构中没有定义主键，那怎么办呢？</span></p>
  <p data-lake-id="uf645008d" id="uf645008d"><span data-lake-id="u7aa9c8f1" id="u7aa9c8f1">​</span><br></p>
  <p data-lake-id="u0f56e166" id="u0f56e166"><span data-lake-id="u357550c3" id="u357550c3">其实，数据库中的每行记录中，除了保存了我们自己定义的一些字段以外，还有一些重要的 db_row_id字段，其实他就是一个数据库帮我添加的隐藏主键，如果我们没有给这个表创建主键，会选择一个不为空的唯一索引来作为聚簇索引，但是如果没有合适的唯一索引，那么会以这个隐藏主键来创建聚簇索引。 </span></p>
  <p data-lake-id="ufd8a95b5" id="ufd8a95b5"><span data-lake-id="uc4736a2e" id="uc4736a2e">​</span><br></p>
  <p data-lake-id="u8e3322e2" id="u8e3322e2"><br></p>
  <p data-lake-id="u79f22bdb" id="u79f22bdb"><span data-lake-id="u7602b517" id="u7602b517">​</span><br></p>
  <p data-lake-id="u373ae102" id="u373ae102"><span data-lake-id="u13225e5b" id="u13225e5b">​</span><br></p>
  <p data-lake-id="u6b1cdd1d" id="u6b1cdd1d"><span data-lake-id="u691c499f" id="u691c499f">​</span><br></p>
 </body>
</html>